import os
import sys
import urllib
from datetime import datetime, timedelta
from utils.redis_helper import RedisHelper
from utils import general_settings
from master import task_settings as settings
from utils.utilities import now_datetime_str


def create_collection_name():
    if len(settings.data_collection) == 0:
        collection_name = settings.start_date_str + '_' + settings.end_date_str
    else:
        collection_name = settings.data_collection

    if len(settings.must_keywords.split()) > 0:
        collection_name += "_" + settings.must_keywords
    if len(settings.included_keywords.split(',')) > 0:
        collection_name += "_" + settings.included_keywords

    if settings.near_me:
        collection_name += '_nearMe'
    return collection_name


def combine_keywords():
    keywords = ''
    if len(settings.must_keywords.strip()) > 0:
        keywords += ' '.join(settings.must_keywords.split(',')) + ' '
    if len(settings.included_keywords.strip()) > 0:
        included_keywords = ' OR '.join(settings.included_keywords.split(','))  # '('+ ')'+
        if len(settings.included_keywords.split(',')) > 1:
            keywords += "(" + included_keywords + ")"
        else:
            keywords += included_keywords
    if len(settings.except_keywords.strip()) > 0:
        keywords += ' -' + ' -'.join(settings.except_keywords.split(','))
    return keywords  # .replace(' ', "%20")


def date_split(start, end, span):
    next_step = start
    date_range_list = []
    while True:
        date_range = []
        date_range.append(next_step)
        next_step = next_step + timedelta(days=span)
        if next_step > end:
            date_range.append(end + timedelta(days=1))
            date_range_list.append(date_range)
            break
        else:
            date_range.append(next_step)
        date_range_list.append(date_range)
    return date_range_list


def create_keyword_commands_list(start_date, end_date, day_span, latest=False):
    ori_url = settings.keywords_url
    date_range_list = date_split(start_date, end_date, day_span)
    commands_list = []
    processed_keywords = urllib.parse.quote(str(combine_keywords()))
    processed_keywords = str(processed_keywords).replace('%28', '(').replace('%29', ')')
    for date_range in date_range_list:
        command = {}
        url = str.format(ori_url, processed_keywords, date_range[0].strftime('%Y-%m-%d'),
                         date_range[1].strftime('%Y-%m-%d'), '%20near%3Ame' if settings.near_me else '')
        referer = str.format(settings.referer_url, processed_keywords, date_range[0].strftime('%Y-%m-%d'),
                             date_range[1].strftime('%Y-%m-%d'), '&lf=on' if settings.near_me else '')
        # if latest:
        #     url += '&f=live' 'csrf': '', 'guest': '',
        command['type'] = general_settings.TwitterConfig().task_type_search
        command['db'] = settings.target_db
        command['tweet_collection'] = create_collection_name()
        if len(settings.userinfo_collection) == 0:
            command['userinfo_collection'] = command['tweet_collection'] + "_userinfo"
        else:
            command['userinfo_collection'] = settings.userinfo_collection
        command['unprocessed_db'] = settings.unprocessed_db
        command['unprocessed_collection'] = settings.unprocessed_collection
        command['url'] = url
        command['referer'] = referer
        command['start_date'] = date_range[0].strftime('%Y-%m-%d')
        command['end_date'] = date_range[1].strftime('%Y-%m-%d')
        commands_list.append(command)
    return commands_list


def create_uid_commands_list(uid_dict_list):
    commands_list = []
    url_header = 'https://twitter.com/'
    for uid_dict in uid_dict_list:
        command = {}
        command['type'] = general_settings.TwitterConfig().task_type_timeline
        command['db'] = settings.target_db
        command['userinfo_collection'] = settings.userinfo_collection if len(settings.userinfo_collection) > 0 else "user_info"
        command['tweet_collection'] = 'user_tweets'
        command['unprocessed_db'] = settings.unprocessed_db
        command['unprocessed_collection'] = settings.unprocessed_collection
        command['userinfo_url'] = str.format(settings.userinfo_url, uid_dict['uid'])
        command['referer'] = url_header + uid_dict['uid']
        command['start_date'] = '1000-01-01'
        command['timeline_url'] = settings.timeline_url
        command['start_date'] = str(uid_dict['start_date'])
        command['start_time'] = str(uid_dict['start_time'])
        commands_list.append(command)
    return commands_list


# 执行两种分发任务：一是按照日期&关键词分发（关键词查找），二是按照uid及截止日期分发（个人时间线获取及更新）
if __name__ == '__main__':
    # 接受日期参数并分解任务，放入redis任务队列（queue：task）
    start_date = None
    end_date = None
    try:
        start_date = datetime.strptime(settings.start_date_str, '%Y-%m-%d')
        end_date = datetime.strptime(settings.end_date_str, '%Y-%m-%d')
    except Exception as e:
        print(now_datetime_str() + "\t\t请检查日期是否输入正确！")
        print(now_datetime_str(), e)
        exit(0)
    if settings.day_span <= 0:
        print(now_datetime_str() + "\t\t日期间隔应大于0")
        exit(0)
    if start_date > end_date:
        print(now_datetime_str() + "\t\t起始日期应不大于终止日期")
        exit(0)
    if len(settings.target_db) <= 0:
        print(now_datetime_str() + "\t\t未指定数据库")
        exit(0)

    if settings.task_type == general_settings.TwitterConfig().task_type_search:
        commands_list = create_keyword_commands_list(start_date, end_date, settings.day_span, settings.latest)
    elif settings.task_type == general_settings.TwitterConfig().task_type_timeline:
        commands_list = create_uid_commands_list(settings.user_list)
    else:
        print(now_datetime_str() + "\t\t任务类型不正确，请检查")
        sys.exit(0)

    # 根据紧急程度选择队列名称
    current_queue_name = general_settings.TwitterConfig().urgent_task_queue if settings.urgent else general_settings.TwitterConfig().task_queue

    mq_client = RedisHelper(host=general_settings.redis_host, port=general_settings.redis_port)
    print(now_datetime_str() + "\t\t当前队列任务总数： " + str(mq_client.get_list_length(current_queue_name)))

    if settings.clear_exist_cmd:
        mq_client.delete_list(current_queue_name)

    for command in commands_list:
        command['queue'] = current_queue_name
        mq_client.write_list(current_queue_name, command)
        print(command)
    print(now_datetime_str() + "\t\t本次生成任务数： " + str(len(commands_list)))
    print(str.format(now_datetime_str() + "\t\t目标任务队列名称：{0}\t\t队列中任务总数：{1}", current_queue_name, str(mq_client.get_list_length(current_queue_name))))
